package com.CRApp.controller;

import com.CRApp.pojo.Address;
import com.CRApp.pojo.Result;
import com.CRApp.service.AddressService;
import com.CRApp.utils.ThreadLocalUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

/**
 * 收货地址控制器
 * 提供符合RESTful规范的收货地址管理接口
 */
@RestController
@RequestMapping("/address")
@Validated
@CrossOrigin
public class AddressController {
    
    private static final Logger logger = LoggerFactory.getLogger(AddressController.class);
    
    // 用于验证路径中的ID是否为数字的正则表达式
    private static final Pattern ID_PATTERN = Pattern.compile("^\\d+$");
    
    @Autowired
    private AddressService addressService;
    
    /**
     * 获取当前登录用户ID
     * @param errorPrefix 错误消息前缀
     * @return 用户ID，如果未登录则返回null
     */
    private Integer getCurrentUserId(String errorPrefix) {
        try {
            Map<String, Object> userInfo = ThreadLocalUtil.get();
            Integer userId = (Integer) userInfo.get("id");
            
            if (userId == null) {
                logger.warn("{}：用户未登录", errorPrefix);
            }
            
            return userId;
        } catch (Exception e) {
            logger.error("{}：获取用户ID失败", errorPrefix, e);
            return null;
        }
    }
    
    /**
     * 验证ID格式并转换为整数
     * @param id ID字符串
     * @param errorPrefix 错误消息前缀
     * @return 转换后的整数ID，如果格式无效则返回null
     */
    private Integer validateAndParseId(String id, String errorPrefix) {
        if (id == null || !ID_PATTERN.matcher(id).matches()) {
            logger.warn("{}：无效的ID格式 - {}", errorPrefix, id);
            return null;
        }
        
        try {
            return Integer.parseInt(id);
        } catch (NumberFormatException e) {
            logger.error("{}：ID解析失败 - {}", errorPrefix, id, e);
            return null;
        }
    }
    
    /**
     * 添加收货地址
     * POST /address - 创建新的收货地址
     * @param params 收货地址信息
     * @return 新增地址的ID
     * 
     * 测试用例：
     * POST http://localhost:8080/address
     * Headers: 
     *   Content-Type: application/json
     *   Authorization: [登录获取的token]
     * Body:
     * {
     *   "recipientName": "张三",
     *   "phone": "13800138000",
     *   "address": "重庆市南岸区学府大道1号"
     * }
     * 预期结果：返回新增地址的ID，状态码200
     */
    @PostMapping
    public Result<?> addAddress(@RequestBody Map<String, String> params) {
        logger.info("收到添加地址请求: {}", params);
        try {
            // 获取当前登录用户ID
            Integer userId = getCurrentUserId("添加失败");
            if (userId == null) {
                return Result.error("添加失败：用户未登录");
            }
            
            // 参数验证
            String recipientName = params.getOrDefault("recipientName", "");
            String phone = params.getOrDefault("phone", "");
            String address = params.getOrDefault("address", "");
            
            if (recipientName.isEmpty()) {
                return Result.error("添加失败：收件人姓名不能为空");
            }
            
            if (phone.isEmpty()) {
                return Result.error("添加失败：联系电话不能为空");
            }
            
            if (address.isEmpty()) {
                return Result.error("添加失败：详细地址不能为空");
            }
            
            // 创建地址对象
            Address addressObj = new Address();
            addressObj.setUserId(userId);
            addressObj.setRecipientName(recipientName);
            addressObj.setPhone(phone);
            addressObj.setAddress(address);
            
            // 添加地址
            Integer addressId = addressService.addAddress(addressObj);
            return addressId != null ? Result.success(addressId) : Result.error("添加失败");
        } catch (Exception e) {
            logger.error("添加地址失败", e);
            return Result.error("添加失败：" + e.getMessage());
        }
    }
    
    /**
     * 更新收货地址
     * PUT /address/{id} - 更新指定ID的收货地址
     * @param addressId 地址ID
     * @param params 更新的信息
     * @return 操作结果
     * 
     * 测试用例：
     * PUT http://localhost:8080/address/1
     * Headers: 
     *   Content-Type: application/json
     *   Authorization: [登录获取的token]
     * Body:
     * {
     *   "recipientName": "李四",
     *   "phone": "13900139000",
     *   "address": "重庆市渝中区解放碑步行街88号"
     * }
     * 预期结果：更新成功，状态码200
     */
    @PutMapping("/{addressId}")
    public Result<?> updateAddress(@PathVariable String addressId, @RequestBody Map<String, String> params) {
        logger.info("收到更新地址请求，ID: {}, 参数: {}", addressId, params);
        try {
            // 验证ID
            Integer addressIdInt = validateAndParseId(addressId, "更新失败");
            if (addressIdInt == null) {
                return Result.error("更新失败：无效的地址ID格式");
            }
            
            // 获取当前登录用户ID
            Integer userId = getCurrentUserId("更新失败");
            if (userId == null) {
                return Result.error("更新失败：用户未登录");
            }
            
            // 获取原有地址信息
            Address existingAddress = addressService.getAddressDetail(addressIdInt);
            if (existingAddress == null) {
                return Result.error("更新失败：地址不存在");
            }
            
            // 验证地址所属权
            if (!existingAddress.getUserId().equals(userId)) {
                return Result.error("更新失败：无权操作此地址");
            }
            
            // 创建更新对象
            Address address = new Address();
            address.setAddressesId(addressIdInt);
            address.setUserId(userId);
            
            // 使用参数更新或保留原值
            address.setRecipientName(params.containsKey("recipientName") ? 
                    params.get("recipientName") : existingAddress.getRecipientName());
            
            address.setPhone(params.containsKey("phone") ? 
                    params.get("phone") : existingAddress.getPhone());
            
            address.setAddress(params.containsKey("address") ? 
                    params.get("address") : existingAddress.getAddress());
            
            // 执行更新
            boolean success = addressService.updateAddress(address);
            return success ? Result.success() : Result.error("更新失败");
        } catch (Exception e) {
            logger.error("更新地址失败", e);
            return Result.error("更新失败：" + e.getMessage());
        }
    }
    
    /**
     * 删除收货地址
     * DELETE /address/{id} - 删除指定ID的收货地址
     * @param addressId 地址ID
     * @return 操作结果
     * 
     * 测试用例：
     * DELETE http://localhost:8080/address/1
     * Headers: 
     *   Authorization: [登录获取的token]
     * 预期结果：删除成功，状态码200
     */
    @DeleteMapping("/{addressId}")
    public Result<?> deleteAddress(@PathVariable String addressId) {
        logger.info("收到删除地址请求，ID: {}", addressId);
        try {
            // 验证ID
            Integer addressIdInt = validateAndParseId(addressId, "删除失败");
            if (addressIdInt == null) {
                return Result.error("删除失败：无效的地址ID格式");
            }
            
            // 获取当前登录用户ID
            Integer userId = getCurrentUserId("删除失败");
            if (userId == null) {
                return Result.error("删除失败：用户未登录");
            }
            
            // 执行删除
            boolean success = addressService.deleteAddress(addressIdInt, userId);
            return success ? Result.success() : Result.error("删除失败：该地址不存在或无权操作");
        } catch (Exception e) {
            logger.error("删除地址失败", e);
            return Result.error("删除失败：" + e.getMessage());
        }
    }
    
    /**
     * 获取用户的所有收货地址
     * GET /address - 获取当前用户的所有收货地址
     * @return 收货地址列表
     * 
     * 测试用例：
     * GET http://localhost:8080/address
     * Headers: 
     *   Authorization: [登录获取的token]
     * 预期结果：返回用户所有地址列表，状态码200
     */
    @GetMapping
    public Result<List<Address>> getUserAddresses() {
        logger.info("收到获取地址列表请求");
        try {
            // 获取当前登录用户ID
            Integer userId = getCurrentUserId("查询失败");
            if (userId == null) {
                return Result.error("查询失败：用户未登录");
            }
            
            // 查询地址列表
            List<Address> addresses = addressService.getUserAddresses(userId);
            return Result.success(addresses);
        } catch (Exception e) {
            logger.error("获取地址列表失败", e);
            return Result.error("查询失败：" + e.getMessage());
        }
    }
    
    /**
     * 获取收货地址详情
     * GET /address/{id} - 获取指定ID的收货地址详情
     * @param addressId 地址ID
     * @return 收货地址详情
     * 
     * 测试用例：
     * GET http://localhost:8080/address/1
     * Headers: 
     *   Authorization: [登录获取的token]
     * 预期结果：返回指定ID的地址详情，状态码200
     */
    @GetMapping("/{addressId}")
    public Result<Address> getAddressDetail(@PathVariable String addressId) {
        logger.info("收到获取地址详情请求，ID: {}", addressId);
        try {
            // 验证ID
            Integer addressIdInt = validateAndParseId(addressId, "查询失败");
            if (addressIdInt == null) {
                return Result.error("查询失败：无效的地址ID格式");
            }
            
            // 获取当前登录用户ID
            Integer userId = getCurrentUserId("查询失败");
            if (userId == null) {
                return Result.error("查询失败：用户未登录");
            }
            
            // 查询地址详情
            Address address = addressService.getAddressDetail(addressIdInt);
            
            // 验证地址归属
            if (address != null && !address.getUserId().equals(userId)) {
                return Result.error("查询失败：无权查看此地址");
            }
            
            return address != null ? Result.success(address) : Result.error("未找到该收货地址");
        } catch (Exception e) {
            logger.error("获取地址详情失败", e);
            return Result.error("查询失败：" + e.getMessage());
        }
    }
    
    /**
     * 兼容/list路径的地址列表查询
     * @return 收货地址列表
     */
    @GetMapping("/list")
    public Result<List<Address>> getAddressList() {
        return getUserAddresses();
    }
}